package session.stateless.CRM;

import entity.CRM.Customer;
import entity.CRM.LineItem;
import entity.CRM.SaleOrder;
import entity.CRM.SaleLead;
import entity.CRM.SaleOrder.StateSaleOrder;
import entity.CRM.SaleQuotation;
import entity.Employee;
import entity.SCM.DeliveryOrder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javaclass.ProductType;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.Query;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import session.stateless.FRM.CreditAccountBeanLocal;


@Stateless
public class SaleOrderBean implements SaleOrderBeanLocal {
    @PersistenceContext()
    EntityManager em;
    @EJB
    CustomerBeanLocal customerSessionBeanLocal;
    @EJB
    SaleLeadBeanLocal saleLeadBeanLocal;
    @EJB
    DiscountBeanLocal discountBeanLocal;
    @EJB
    CreditAccountBeanLocal creditAccountBeanLocal;
    
    DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    
    public Long convertToSaleOrder(String reg_num, Long saleQuotationId, List<LineItem> lineItems) 
    {
        Customer customer = em.find(Customer.class, reg_num);
        
        if (customer == null)
        {
            SaleLead saleLead = em.find(SaleLead.class, reg_num);
            if (saleLead != null)
            {
                customerSessionBeanLocal.convertCustomerFromSaleLead(saleLead.getRegistrationNumber());
                customer = em.find(Customer.class, reg_num);
            }            
        }
        
        SaleQuotation saleQuotation = em.find(SaleQuotation.class, saleQuotationId);        
        
        SaleOrder saleOrder = new SaleOrder();
        
        saleOrder.setCustomer(customer);
        saleOrder.setSaleQuotation(saleQuotation);
        saleOrder.setLineItems(lineItems);
        saleOrder.setStateSaleOrder(StateSaleOrder.Pending);
        Date date = new Date();
        saleOrder.setSaleOrderDate(dateFormat.format(date));
        em.persist(saleOrder);
        
        customer.getSaleOrders().add(saleOrder);
        em.flush();
        
        return saleOrder.getId();
    }

    @Override
    public List<SaleOrder> getSaleOrders(Long id) {
        Employee executive = em.find(Employee.class, id);
        Query q = em.createQuery("SELECT c FROM Customer c WHERE c.customerExecutive=:executive");
        q.setParameter("executive", executive);
        List<Customer> customers = (List<Customer>) q.getResultList();

        List<SaleOrder> saleOrderList = new ArrayList<SaleOrder>();

        for (Customer c : customers)
        {
            for (SaleOrder s : c.getSaleOrders())
            {
                saleOrderList.add(s);
            }
        }
        
        return saleOrderList;
    }
    @Override
    public List<SaleOrder> getSaleOrders_ConfirmedOnly() {
        Query q = em.createQuery("SELECT c FROM SaleOrder c WHERE c.stateSaleOrder = :state");
        q.setParameter("state", SaleOrder.StateSaleOrder.Confirmed);

        List<SaleOrder> saleOrderList = q.getResultList();
        return saleOrderList;
    }
    @Override
    public List<SaleOrder> getSaleOrders_Confirmed() {
        Query q = em.createQuery("SELECT c FROM SaleOrder c WHERE c.stateSaleOrder = :state");
        q.setParameter("state", SaleOrder.StateSaleOrder.Confirmed);

        List<SaleOrder> saleOrderList = q.getResultList();
        List<SaleOrder> saleOrders = new ArrayList<SaleOrder>();

        if (saleOrderList.isEmpty()) {
            return null;
        }

        for (int i = 0; i < saleOrderList.size(); i++) {
            SaleOrder saleOrder = new SaleOrder();
            saleOrder = saleOrderList.get(i);
            boolean complete = true;
            if (saleOrder.getDeliveryOrders().isEmpty()) {
                saleOrders.add(saleOrder);
            } else {
                List<LineItem> lineItemList = saleOrder.getLineItems();
                List<DeliveryOrder> deliveryOrderList = saleOrder.getDeliveryOrders();
                for (int j = 0; j < lineItemList.size(); j++) {
                    complete = true;
                    LineItem selectedLineItem = new LineItem();
                    selectedLineItem = lineItemList.get(j);
                    ProductType productType = selectedLineItem.getProductPrice().getProductType();
                    long quantity = 0;
                    for (int k = 0; k < deliveryOrderList.size(); k++) {
                        for (int m = 0; m < deliveryOrderList.get(k).getProductLines().size(); m++) {

                            if (deliveryOrderList.get(k).getProductLines().get(m).getProduct().getProductType().equals(productType)) {
                                quantity += deliveryOrderList.get(k).getProductLines().get(m).getQuantity().longValue();
                            }
                        }
                    }

                    if (selectedLineItem.getLineItemQuantity().longValue() > quantity) {
                        complete = false;
                    }

                }

                if (!complete) {
                    saleOrders.add(saleOrder);
                }
            }
        }

        return saleOrders;
    }
    
    @Override
    public List<SaleOrder> getSaleOrdersByCustomer(String reg_num) {
        Customer customer = em.find(Customer.class, reg_num);
        return customer.getSaleOrders();
    }
    
    @Override
    public void updateSaleOrder(Long saleOrderId, List<LineItem> lineItems){
        SaleOrder saleOrder = em.find(SaleOrder.class, saleOrderId);
        if (saleOrder == null)
            System.out.println("Sale Order does not exist. Please try again.");
        else
        {
            saleOrder.setLineItems(lineItems);
            em.flush();
        }
    }
    
    @Override
    public void updateStatus(Long id, SaleOrder.StateSaleOrder state)
    {
        SaleOrder saleOrder = em.find(SaleOrder.class, id);
        saleOrder.setStateSaleOrder(state);
        em.flush();
    }
    
    @Override
    public void deleteSaleOrder(Long saleOrderId)
    {
        SaleOrder saleOrder = em.find(SaleOrder.class, saleOrderId);
        if(saleOrder == null)
            System.out.println("No Sale Order Found.");
        else
           {
//            Customer temp_customer = saleOrder.getCustomer();
//            List<SaleOrder> temp_saleOrders = temp_customer.getSaleOrders();
//            temp_saleOrders.remove(saleOrder);
//            temp_customer.setSaleOrders(temp_saleOrders);
//          
            List<LineItem> temp=saleOrder.getLineItems();
            saleOrder.setLineItems(null);
            
            for (LineItem lineItem: temp)
            {
                em.remove(lineItem);
            }
            saleOrder.getCustomer().getSaleOrders().remove(saleOrder);
            em.flush();
            em.remove(saleOrder);
            em.flush();
        }
    }

    @Override
    public SaleOrder findSaleOrder(Long saleOrderId) {
        return (SaleOrder) em.find(SaleOrder.class, saleOrderId);
    }

    @Override
    public boolean havingCashInAdvance(Long saleOrderId) {
        SaleOrder saleOrder = em.find(SaleOrder.class, saleOrderId);
        if (saleOrder.getCashInAdvance()!=null)
        {
            if (saleOrder.getCashInAdvance().getCashInAdvanceAmount()>0)
                return true;
            else return false;            
        }
        return false;
    }

    

}
